//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __ELASTOS_IO_H__
#define __ELASTOS_IO_H__

typedef uint32_t    ioport_t;

#define InbDelay(port)              Inb(port)
#define InwDelay(port)              Inw(port)
#define InlDelay(port)              Inl(port)

#define OutbDelay(port, data)       Outb(port, data)
#define OutwDelay(port, data)       Outw(port, data)
#define OutlDelay(port, data)       Outl(port, data)

#define Ind(port)                   Inl(port)
#define Insd(port, buffer, size)    Insl((port), (buffer), (size))
#define Outd(port, data)            Outl((port), (data))
#define Outsd(port, buffer, size)   Outsl((port), (buffer), (size))
#define IndDelay(port)              InlDelay(port)
#define OutdDelay(port, data)       OutlDelay((port), (data))

INLINE uint8_t Inb(ioport_t port)
{
    return *(volatile uint8_t *)port;
}

INLINE uint16_t Inw(ioport_t port)
{
    return *(volatile uint16_t *)port;
}

INLINE uint32_t Inl(ioport_t port)
{
    return *(volatile uint32_t *)port;
}

INLINE void Insb(ioport_t port, void *buffer, size_t size)
{
    while (size--) {
        *(uint8_t *)buffer = *(volatile uint8_t *)port;
        buffer = ((uint8_t *)buffer) + 1;
    }
}

INLINE void Insw(ioport_t port, void *buffer, size_t size)
{
    size >>= 1;
    while (size--) {
        *(uint16_t *)buffer = *(volatile uint16_t *)port;
        buffer = (uint16_t *)buffer + 1;
    }
}

INLINE void Insl(ioport_t port, void *buffer, size_t size)
{
    size >>= 2;
    while (size--) {
        *(uint32_t *)buffer = *(volatile uint32_t *)port;
        buffer = ((uint32_t *)buffer) + 1;
    }
}

INLINE void Outb(ioport_t port, uint8_t u8Data)
{
    *(volatile uint8_t *)port = u8Data;
}

INLINE void Outw(ioport_t port, uint16_t u16Data)
{
    *(volatile uint16_t *)port = u16Data;
}

INLINE void Outl(ioport_t port, uint32_t u32Data)
{
    *(volatile uint32_t *)port = u32Data;
}

INLINE void Outsb(ioport_t port, const void *buffer, size_t size)
{
    while (size--) {
        *(volatile uint8_t *)port = *(uint8_t *)buffer;
        buffer = ((uint8_t *)buffer) + 1;
    }
}

INLINE void Outsw(ioport_t port, const void *buffer, size_t size)
{
    size >>= 1;
    while (size--) {
        *(volatile uint16_t *)port = *(uint16_t *)buffer;
        buffer = ((uint16_t *)buffer) + 1;
    }
}

INLINE void Outsl(ioport_t port, const void *buffer, size_t size)
{
    size >>= 2;
    while (size--) {
        *(volatile uint32_t *)port = *(uint32_t *)buffer;
        buffer = ((uint32_t *)buffer) + 1;
    }
}

#endif //__ELASTOS_IO_H__
